//工具已经迁移到 https://gitee.com/a592622272/compare-utils
//适用于大数据比较工具，待完善......................将来合并到：CompareUtils

//package shotgun.my.sweetutil;
//
//import java.io.Serializable;
//import java.util.ArrayList;
//import java.util.Collection;
//import java.util.Collections;
//import java.util.Comparator;
//import java.util.LinkedHashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.Objects;
//import java.util.Set;
//import java.util.TreeSet;
//import java.util.function.Function;
//import java.util.stream.Collectors;
//
//import static java.util.stream.Collectors.collectingAndThen;
//import static java.util.stream.Collectors.toCollection;
//
///**
// * 数据对比工具类
// *
// * @author wulingming
// * @date 2021/11/18 14:40
// **/
//public class CompareUtils2FromDb {
//
//
//    /**
//     * 比较结果
//     *
//     * @author wulingming
//     * @date 2021/11/18 16:18
//     **/
//    public static class CompareResult<T> implements Serializable {
//
//        private static final long serialVersionUID = 6156436360677906070L;
//
//        /**
//         * 删除类型
//         */
//        private List<T> needDeleteTarget;
//        /**
//         * 新增类型
//         */
//        private List<T> needAddSource;
//        /**
//         * 修改类型
//         */
//        private List<T> needUpdateSource;
//        /**
//         * 修改类型：数据相同(可以不用入库)
//         * getCompareIsSame有值时:返回结果needUpdateSameSource才有数据
//         */
//        private List<T> needUpdateSameSource;
//
//        public List<T> getNeedDeleteTarget() {
//            return needDeleteTarget;
//        }
//
//        public void setNeedDeleteTarget(List<T> needDeleteTarget) {
//            this.needDeleteTarget = needDeleteTarget;
//        }
//
//        public List<T> getNeedAddSource() {
//            return needAddSource;
//        }
//
//        public void setNeedAddSource(List<T> needAddSource) {
//            this.needAddSource = needAddSource;
//        }
//
//        public List<T> getNeedUpdateSource() {
//            return needUpdateSource;
//        }
//
//        public void setNeedUpdateSource(List<T> needUpdateSource) {
//            this.needUpdateSource = needUpdateSource;
//        }
//
//        public List<T> getNeedUpdateSameSource() {
//            return needUpdateSameSource;
//        }
//
//        public void setNeedUpdateSameSource(List<T> needUpdateSameSource) {
//            this.needUpdateSameSource = needUpdateSameSource;
//        }
//    }
//
//    /**
//     * 比较两批数据，标记增删改。（一般用于全量更新表数据）
//     * <p>
//     * 1：传入实体没有，数据库有：删除操作
//     * 2；传入实体有，数据库有：修改操作
//     * 3：传入实体有，数据库没有：新增操作
//     *
//     * @param sourse           数据源（一般是待入库的数据）
//     * @param target           目标数据（一般是数据库的数据）
//     * @param getUniqueFlag    获取唯一标识
//     * @param getCompareIsSame 获取对象数据字符串形式，用于比较数据是否相同（getCompareIsSame有值时:返回结果needUpdateSameSource有数据）。比如：除了对比主键是否一致，还要对比各个字段是否一致。
//     *                         比如：member -> JSON.toJSONString(Arrays.asList(member.getName(), member.getSelf()))。不建议使用将对象直接输出json，字段排序有可能不一致
//     * @return 比较结果
//     * @author wulingming
//     */
//    public static <T> CompareResult<T> compare(Collection<T> sourse, Collection<T> target, Function<T, String> getUniqueFlag, Function<T, String> getCompareIsSame) {
//        if (sourse == null) {
//            sourse = Collections.emptyList();
//        }
//        if (target == null) {
//            target = Collections.emptyList();
//        }
//        if (getUniqueFlag == null) {
//            throw new IllegalArgumentException("getUniqueFlag参数不能为空！");
//        }
//
//
//        //数据源去重
//        sourse = sourse.stream().filter(Objects::nonNull).collect(collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(getUniqueFlag))), ArrayList::new));
//
//        //“数据源”唯一标识 set比list查找速度更快。
//        Set<String> sourUniqueFlags = sourse.stream().map(getUniqueFlag).collect(Collectors.toSet());
//        //“目标数据”唯一标识
//        Map<String, T> targetUniqueFlagMap = target.stream().filter(Objects::nonNull).collect(Collectors.toMap(getUniqueFlag, o -> o, (o, o2) -> o));
//
//        // 1：传入实体没有，数据库有：删除操作(id有值)
//        List<T> needDeleteTarget = target.stream().filter(Objects::nonNull).filter(t -> !sourUniqueFlags.contains(getUniqueFlag.apply(t))).collect(Collectors.toList());
//
//        // 3：传入实体有，数据库没有：新增操作(id无值，需要调用者自己设置)
//        List<T> needAddSource = sourse.stream().filter(t -> !targetUniqueFlagMap.containsKey(getUniqueFlag.apply(t))).collect(Collectors.toList());
//
//        List<T> needUpdateSource;
//        List<T> needUpdateSameSource;
//        if (getCompareIsSame == null) {
//            //只检查唯一标识是否存在，不检测数据是否相同
//
//            //2；传入实体有，数据库有：修改操作
//            needUpdateSource = sourse.stream().filter(t -> targetUniqueFlagMap.containsKey(getUniqueFlag.apply(t))).collect(Collectors.toList());
//            needUpdateSameSource = Collections.emptyList();
//        } else {
//            //检测唯一标识，并且比较数据是否相同
//
//            //2；传入实体有，数据库有：修改操作（数据不同）
//            needUpdateSource = sourse.stream().filter(t -> {
//                String uniqueFlag = getUniqueFlag.apply(t);
//                return targetUniqueFlagMap.containsKey(uniqueFlag) && Comparator.comparing(getCompareIsSame).compare(t, targetUniqueFlagMap.get(uniqueFlag)) != 0;
//            }).collect(Collectors.toList());
//
//            //2；传入实体有，数据库有：修改操作（数据相同）
//            needUpdateSameSource = sourse.stream().filter(t -> {
//                String uniqueFlag = getUniqueFlag.apply(t);
//                return targetUniqueFlagMap.containsKey(uniqueFlag) && Comparator.comparing(getCompareIsSame).compare(t, targetUniqueFlagMap.get(uniqueFlag)) == 0;
//            }).collect(Collectors.toList());
//        }
//
//        CompareResult<T> result = new CompareResult<>();
//        result.setNeedDeleteTarget(needDeleteTarget);
//        result.setNeedAddSource(needAddSource);
//        result.setNeedUpdateSource(needUpdateSource);
//        result.setNeedUpdateSameSource(needUpdateSameSource);
//
//        return result;
//    }
//
//    /**
//     * 比较两批数据，标记增删改。（一般用于全量更新表数据）
//     * <p>
//     * 1：传入实体没有，数据库有：删除操作
//     * 2；传入实体有，数据库有：修改操作
//     * 3：传入实体有，数据库没有：新增操作
//     *
//     * @param sourse        数据源（一般是待入库的数据）
//     * @param target        目标数据（一般是数据库的数据）
//     * @param getUniqueFlag 唯一标识
//     * @return 比较结果(返回结果needUpdateSameSource没有数据)
//     * @author wulingming
//     */
//    public static <T> CompareResult<T> compare(Collection<T> sourse, Collection<T> target, Function<T, String> getUniqueFlag) {
//        return compare(sourse, target, getUniqueFlag, null);
//    }
//
//
//
//    public interface CompareInDbInterface{
//        public List<>
//    }
//
//
//    /**
//     * 在数据库中进行对比，适用于大数据比较
//     * （建议手动数据源去重，避免重复数据）
//     **/
//    public static <T,U extends Comparable<? super U>> CompareResult<T> compareInDb(Collection<T> sourse, Function<T, LinkedHashMap<String, U>> getUniqueFlag, CompareInDbInterface compareInDbInterface) {
//        if (sourse == null) {
//            sourse = Collections.emptyList();
//        }
//        if (getUniqueFlag == null) {
//            throw new IllegalArgumentException("getUniqueFlag参数不能为空！");
//        }
//        if (compareInDbInterface == null) {
//            throw new IllegalArgumentException("compareInDbInterface参数不能为空！");
//        }
//
//        //数据源去重
//        sourse = sourse.stream().filter(Objects::nonNull).collect(collectingAndThen(toCollection(() -> new TreeSet<>(Comparator.comparing(o -> {
//            getUniqueFlag.apply(o);
//        }))), ArrayList::new));
//
//
//        //“数据源”唯一标识 set比list查找速度更快。
//        Set<String> sourUniqueFlags = sourse.stream().map(getUniqueFlag).collect(Collectors.toSet());
//
//
//        // 1：传入实体没有，数据库有：删除操作(id有值)
//        List<T> needDeleteTarget = target.stream().filter(Objects::nonNull).filter(t -> !sourUniqueFlags.contains(getUniqueFlag.apply(t))).collect(Collectors.toList());
//
//
//
//
//
//        // 3：传入实体有，数据库没有：新增操作(id无值，需要调用者自己设置)
//        List<T> needAddSource = sourse.stream().filter(t -> !targetUniqueFlagMap.containsKey(getUniqueFlag.apply(t))).collect(Collectors.toList());
//
//        List<T> needUpdateSource;
//        List<T> needUpdateSameSource;
//        if (getCompareIsSame == null) {
//            //只检查唯一标识是否存在，不检测数据是否相同
//
//            //2；传入实体有，数据库有：修改操作
//            needUpdateSource = sourse.stream().filter(t -> targetUniqueFlagMap.containsKey(getUniqueFlag.apply(t))).collect(Collectors.toList());
//            needUpdateSameSource = Collections.emptyList();
//        } else {
//            //检测唯一标识，并且比较数据是否相同
//
//            //2；传入实体有，数据库有：修改操作（数据不同）
//            needUpdateSource = sourse.stream().filter(t -> {
//                String uniqueFlag = getUniqueFlag.apply(t);
//                return targetUniqueFlagMap.containsKey(uniqueFlag) && Comparator.comparing(getCompareIsSame).compare(t, targetUniqueFlagMap.get(uniqueFlag)) != 0;
//            }).collect(Collectors.toList());
//
//            //2；传入实体有，数据库有：修改操作（数据相同）
//            needUpdateSameSource = sourse.stream().filter(t -> {
//                String uniqueFlag = getUniqueFlag.apply(t);
//                return targetUniqueFlagMap.containsKey(uniqueFlag) && Comparator.comparing(getCompareIsSame).compare(t, targetUniqueFlagMap.get(uniqueFlag)) == 0;
//            }).collect(Collectors.toList());
//        }
//
//        CompareResult<T> result = new CompareResult<>();
//        result.setNeedDeleteTarget(needDeleteTarget);
//        result.setNeedAddSource(needAddSource);
//        result.setNeedUpdateSource(needUpdateSource);
//        result.setNeedUpdateSameSource(needUpdateSameSource);
//
//        return result;
//    }
//
//    //测试工具类
////    public static void main(String[] args) {
////        Member m0 = new Member();
////        m0.setName("m1");
////        Member m1 = new Member();
////        m1.setName("m1");
////        Member m2 = new Member();
////        m2.setName("m2");
////        Member m3 = new Member();
////        m3.setName("m3,\"\"\"\"\",,, ");
////
////        Member tm2 = new Member();
////        tm2.setName("m2");
////        Member tm3 = new Member();
////        tm3.setName("m3,\"\"\"\"\",,, ");
////        tm3.setSelf(true);
////        Member tm4 = new Member();
////        tm4.setName("m4,\"\"\"\"\",,, ");
////
////        List<Member> members1 = Arrays.asList(m0, m1, m2, m3, null);
////        List<Member> members2 = Arrays.asList(tm2, tm3, tm4, null);
////
////        CompareResult<Member> compare = compare(members1, members2, MemberEntity::getName, member -> JSON.toJSONString(Arrays.asList(member.getName(), member.getSelf())));
////
////        System.out.println(JSON.toJSONString(compare));
////
////    }
//
//
//}
